// Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.

namespace Microsoft.FSharp.Collections

open System
open System.Collections
open Microsoft.FSharp.Core
open Microsoft.FSharp.Collections
    
/// <summary>Contains operations for working with values of type <see cref="T:Microsoft.FSharp.Collections.seq`1"/>.</summary>
[<RequireQualifiedAccess>]
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Seq = 

    /// <summary>Returns a new sequence that contains all pairings of elements from the first and second sequences.</summary>
    ///
    /// <param name="source1">The first sequence.</param>
    /// <param name="source2">The second sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input sequences is null.</exception>
    ///
    /// <example id="all-pairs-1">
    /// <code lang="fsharp">
    /// ([1; 2], [3; 4]) ||> Seq.allPairs
    /// </code>
    /// Evaluates to a sequence yielding the same results as
    /// <code>
    /// seq { (1, 3); (1, 4); (2, 3); (2, 4) }
    /// </code>
    /// </example>
    [<CompiledName("AllPairs")>]
    val allPairs: source1:seq<'T1> -> source2:seq<'T2> -> seq<'T1 * 'T2>

    /// <summary>Wraps the two given enumerations as a single concatenated
    /// enumeration.</summary>
    ///
    /// <remarks>The returned sequence may be passed between threads safely. However, 
    /// individual IEnumerator values generated from the returned sequence should not be accessed
    /// concurrently.</remarks>
    ///
    /// <param name="source1">The first sequence.</param>
    /// <param name="source2">The second sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the two provided sequences is
    /// null.</exception>
    ///
    /// <example id="append-1">
    /// <code lang="fsharp">
    /// Seq.append [1; 2] [3; 4]
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 1; 2; 3; 4 }</c>
    /// </example>
    [<CompiledName("Append")>]
    val append: source1:seq<'T>  -> source2:seq<'T> -> seq<'T>

    /// <summary>Returns the average of the elements in the sequence.</summary>
    ///
    /// <remarks>The elements are averaged using the <c>+</c> operator, <c>DivideByInt</c> method and <c>Zero</c> property
    /// associated with the element type.</remarks>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The average.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input sequence has zero elements.</exception>
    ///
    /// <example id="average-1">
    /// <code lang="fsharp">
    /// [1.0; 2.0; 3.0] |> Seq.average
    /// </code>
    /// Evaluates to <c>2.0</c>
    /// </example>
    ///
    /// <example id="average-2">
    /// <code lang="fsharp">
    /// [] |> Seq.average
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("Average")>]
    val inline average   : source:seq<(^T)> -> ^T
                                  when ^T : (static member ( + ) : ^T * ^T -> ^T)
                                  and  ^T : (static member DivideByInt : ^T * int -> ^T)
                                  and  ^T : (static member Zero : ^T)

    /// <summary>Returns the average of the results generated by applying the function to each element
    /// of the sequence.</summary>
    ///
    /// <remarks>The elements are averaged using the <c>+</c> operator, <c>DivideByInt</c> method and <c>Zero</c> property
    /// associated with the generated type.</remarks>
    ///
    /// <param name="projection">A function applied to transform each element of the sequence.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The average.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input sequence has zero elements.</exception>
    ///
    /// <example id="average-by-1">
    /// <code lang="fsharp">
    /// type Foo = { Bar: float }
    ///
    /// let input = seq { {Bar = 2.0}; {Bar = 4.0} }
    ///
    /// input |> Seq.averageBy (fun foo -> foo.Bar)
    /// </code>
    /// Evaluates to <c>3.0</c>
    /// </example>
    ///
    /// <example id="average-by-2">
    /// <code lang="fsharp">
    /// type Foo = { Bar: float }
    ///
    /// Seq.empty |> Seq.averageBy (fun (foo: Foo) -> foo.Bar)
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("AverageBy")>]
    val inline averageBy   : projection:('T -> ^U) -> source:seq<'T>  -> ^U
                                  when ^U : (static member ( + ) : ^U * ^U -> ^U)
                                  and  ^U : (static member DivideByInt : ^U * int -> ^U)
                                  and  ^U : (static member Zero : ^U)

    /// <summary>Returns a sequence that corresponds to a cached version of the input sequence.</summary>
    ///
    /// <remarks>
    /// The result sequence will have the same elements as the input sequence. The result
    /// can be enumerated multiple times. The input sequence will be enumerated at most
    /// once and only as far as is necessary.  Caching a sequence is typically useful when repeatedly
    /// evaluating items in the original sequence is computationally expensive or if
    /// iterating the sequence causes side-effects that the user does not want to be
    /// repeated multiple times.
    ///
    /// Enumeration of the result sequence is thread safe in the sense that multiple independent IEnumerator
    /// values may be used simultaneously from different threads (accesses to
    /// the internal lookaside table are thread safe). Each individual IEnumerator
    /// is not typically thread safe and should not be accessed concurrently.
    ///
    /// Once enumeration of the input sequence has started,
    /// it's enumerator will be kept live by this object until the enumeration has completed.
    /// At that point, the enumerator will be disposed.
    ///
    /// The enumerator may be disposed and underlying cache storage released by
    /// converting the returned sequence object to type IDisposable, and calling the Dispose method
    /// on this object. The sequence object may then be re-enumerated and a fresh enumerator will
    /// be used.</remarks>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="cache-1">
    /// <code lang="fsharp">
    /// let fibSeq =(0, 1) |> Seq.unfold (fun (a,b) -> Some(a + b, (b, a + b)))
    ///
    /// let fibSeq3 = fibSeq |> Seq.take 3 |> Seq.cache
    /// fibSeq3
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 1; 2; 3 }</c>,
    /// and it will not do the calculation again when called.
    /// </example>
    [<CompiledName("Cache")>]
    val cache: source:seq<'T> -> seq<'T>

    /// <summary>Wraps a loosely-typed System.Collections sequence as a typed sequence.</summary>
    ///
    /// <remarks>The use of this function usually requires a type annotation.
    /// An incorrect type annotation may result in runtime type
    /// errors.
    /// Individual IEnumerator values generated from the returned sequence should not be accessed concurrently.</remarks>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="cast-1">
    /// <code lang="fsharp">
    /// [box 1; box 2; box 3] |> Seq.cast&lt;int&gt;
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 1; 2; 3 }</c>, explicitly typed as <c>seq&lt;int&gt;</c>.
    /// </example>
    [<CompiledName("Cast")>]
    val cast: source:IEnumerable -> seq<'T>

    /// <summary>Applies the given function to each element of the sequence. Returns
    /// a sequence comprised of the results "x" for each element where
    /// the function returns Some(x).</summary>
    ///
    /// <remarks>The returned sequence may be passed between threads safely. However,
    /// individual IEnumerator values generated from the returned sequence should not
    /// be accessed concurrently.</remarks>
    ///
    /// <param name="chooser">A function to transform items of type T into options of type U.</param>
    /// <param name="source">The input sequence of type T.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="choose-1">
    /// <code lang="fsharp">
    /// [Some 1; None; Some 2] |> Seq.choose id
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 1; 2 }</c>
    /// </example>
    ///
    /// <example id="choose-2">
    /// <code lang="fsharp">
    /// [1; 2; 3] |> Seq.choose (fun n -> if n % 2 = 0 then Some n else None)
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 2 }</c>
    /// </example>
    [<CompiledName("Choose")>]
    val choose: chooser:('T -> 'U option) -> source:seq<'T> -> seq<'U>

    /// <summary>Divides the input sequence into chunks of size at most <c>chunkSize</c>.</summary>
    ///
    /// <param name="chunkSize">The maximum size of each chunk.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The sequence divided into chunks.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when <c>chunkSize</c> is not positive.</exception>
    ///
    /// <example id="chunk-by-size-1">
    /// <code lang="fsharp">
    /// [1; 2; 3] |> Seq.chunkBySize 2
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { [|1; 2|]; [|3|] }</c>
    /// </example>
    ///
    /// <example id="chunk-by-size-2">
    /// <code lang="fsharp">
    /// [1; 2; 3] |> Seq.chunkBySize -2
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("ChunkBySize")>]
    val chunkBySize: chunkSize:int -> source:seq<'T> -> seq<'T[]>

    /// <summary>Applies the given function to each element of the sequence and concatenates all the
    /// results.</summary>
    ///
    /// <remarks>Remember sequence is lazy, effects are delayed until it is enumerated.</remarks>
    ///
    /// <param name="mapping">A function to transform elements of the input sequence into the sequences
    /// that will then be concatenated.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="collect-1">
    /// <code lang="fsharp">
    /// type Foo = { Bar: int seq }
    ///
    /// let input = seq { {Bar = [1; 2]}; {Bar = [3; 4]} }
    ///
    /// input |> Seq.collect (fun foo -> foo.Bar)
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 1; 2; 3; 4 }</c>
    /// </example>
    ///
    /// <example id="collect-2">
    /// <code lang="fsharp">
    /// let input = [[1; 2]; [3; 4]]
    ///
    /// input |> Seq.collect id
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 1; 2; 3; 4 }</c>
    /// </example>
    [<CompiledName("Collect")>]
    val collect: mapping:('T -> 'Collection) -> source:seq<'T> -> seq<'U>  when 'Collection :> seq<'U>

    /// <summary>Compares two sequences using the given comparison function, element by element.</summary>
    ///
    /// <param name="comparer">A function that takes an element from each sequence and returns an int.
    /// If it evaluates to a non-zero value iteration is stopped and that value is returned.</param>
    /// <param name="source1">The first input sequence.</param>
    /// <param name="source2">The second input sequence.</param>
    ///
    /// <returns>Returns the first non-zero result from the comparison function.  If the end of a sequence
    /// is reached it returns a -1 if the first sequence is shorter and a 1 if the second sequence
    /// is shorter.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input sequences
    /// is null.</exception>
    ///
    /// <example id="compare-with-1">
    /// <code lang="fsharp">
    /// let closerToNextDozen a b =
    ///   (a % 12).CompareTo(b % 12)
    ///
    /// let input1 = [1; 10]
    /// let input2 = [1; 10]
    ///
    /// (input1, input2) ||> Seq.compareWith closerToNextDozen
    /// </code>
    /// Evaluates to <c>0</c>
    /// </example>
    ///
    /// <example id="compare-with-2">
    /// <code lang="fsharp">
    /// let closerToNextDozen a b =
    ///   (a % 12).CompareTo(b % 12)
    ///
    /// let input1 = [1; 5]
    /// let input2 = [1; 8]
    ///
    /// (input1, input2) ||> Seq.compareWith closerToNextDozen
    /// </code>
    /// Evaluates to <c>-1</c>
    /// </example>
    ///
    /// <example id="compare-with-3">
    /// <code lang="fsharp">
    /// let closerToNextDozen a b =
    ///   (a % 12).CompareTo(b % 12)
    ///
    /// let input1 = [1; 11]
    /// let input2 = [1; 13]
    ///
    /// (input1, input2) ||> Seq.compareWith closerToNextDozen
    /// </code>
    /// Evaluates to <c>1</c>
    /// </example>
    ///
    /// <example id="compare-with-4">
    /// <code lang="fsharp">
    /// let closerToNextDozen a b =
    ///   (a % 12).CompareTo(b % 12)
    ///
    /// let input1 = [1; 2]
    /// let input2 = [1]
    ///
    /// (input1, input2) ||> Seq.compareWith closerToNextDozen
    /// </code>
    /// Evaluates to <c>1</c>
    /// </example>
    ///
    /// <example id="compare-with-5">
    /// <code lang="fsharp">
    /// let closerToNextDozen a b =
    ///   (a % 12).CompareTo(b % 12)
    ///
    /// let input1 = [1]
    /// let input2 = [1; 2]
    ///
    /// (input1, input2) ||> Seq.compareWith closerToNextDozen
    /// </code>
    /// Evaluates to <c>-1</c>
    /// </example>
    [<CompiledName("CompareWith")>]
    val compareWith: comparer:('T -> 'T -> int) -> source1:seq<'T> -> source2:seq<'T> -> int

    /// <summary>Combines the given enumeration-of-enumerations as a single concatenated
    /// enumeration.</summary>
    ///
    /// <remarks>The returned sequence may be passed between threads safely. However,
    /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently.</remarks>
    ///
    /// <param name="sources">The input enumeration-of-enumerations.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="concat-1">
    /// <code lang="fsharp">
    /// let inputs = [[1; 2]; [3]; [4; 5]]
    ///
    /// inputs |> Seq.concat
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 1; 2; 3; 4; 5 }</c>
    /// </example>
    [<CompiledName("Concat")>]
    val concat: sources:seq<'Collection> -> seq<'T> when 'Collection :> seq<'T>

    /// <summary>Tests if the sequence contains the specified element.</summary>
    ///
    /// <param name="value">The value to locate in the input sequence.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>True if the input sequence contains the specified element; false otherwise.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="contains-1">
    /// <code lang="fsharp">
    /// [1; 2] |> Seq.contains 2 // evaluates to true
    /// [1; 2] |> Seq.contains 5 // evaluates to false
    /// </code>
    /// </example>
    [<CompiledName("Contains")>]
    val inline contains: value:'T -> source:seq<'T> -> bool when 'T : equality

    /// <summary>Applies a key-generating function to each element of a sequence and returns a sequence yielding unique
    /// keys and their number of occurrences in the original sequence.</summary>
    ///
    /// <remarks>Note that this function returns a sequence that digests the whole initial sequence as soon as
    /// that sequence is iterated. As a result this function should not be used with
    /// large or infinite sequences. The function makes no assumption on the ordering of the original
    /// sequence.</remarks>
    ///
    /// <param name="projection">A function transforming each item of the input sequence into a key to be
    /// compared against the others.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="count-by-1">
    /// <code lang="fsharp">
    /// type Foo = { Bar: string }
    ///
    /// let inputs = [{Bar = "a"}; {Bar = "b"}; {Bar = "a"}]
    ///
    /// inputs |> Seq.countBy (fun foo -> foo.Bar)
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { ("a", 2); ("b", 1) }</c>
    /// </example>
    [<CompiledName("CountBy")>]
    val countBy: projection:('T -> 'Key) -> source:seq<'T> -> seq<'Key * int> when 'Key : equality

    /// <summary>Returns a sequence that is built from the given delayed specification of a
    /// sequence.</summary>
    ///
    /// <remarks>The input function is evaluated each time an IEnumerator for the sequence
    /// is requested.</remarks>
    ///
    /// <param name="generator">The generating function for the sequence.</param>
    /// <returns>The result sequence.</returns>
    ///
    /// <example id="delay-1">
    /// <code lang="fsharp">
    /// Seq.delay (fun () -> Seq.ofList [1; 2; 3])
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 1; 2; 3 }</c>, executing
    /// the generator function every time is consumed.
    /// </example>
    [<CompiledName("Delay")>]
    val delay: generator:(unit -> seq<'T>) -> seq<'T>

    /// <summary>Returns a sequence that contains no duplicate entries according to generic hash and
    /// equality comparisons on the entries.
    /// If an element occurs multiple times in the sequence then the later occurrences are discarded.</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="distinct-1">
    /// <code lang="fsharp">
    /// [1; 1; 2; 3] |> Seq.distinct
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 1; 2; 3 }</c>
    /// </example>
    [<CompiledName("Distinct")>]
    val distinct: source:seq<'T> -> seq<'T> when 'T : equality

    /// <summary>Returns a sequence that contains no duplicate entries according to the
    /// generic hash and equality comparisons on the keys returned by the given key-generating function.
    /// If an element occurs multiple times in the sequence then the later occurrences are discarded.</summary>
    ///
    /// <param name="projection">A function transforming the sequence items into comparable keys.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="distinct-by-1">
    /// <code lang="fsharp">
    /// let inputs = [{Bar = 1 };{Bar = 1}; {Bar = 2}; {Bar = 3}]
    ///
    /// inputs |> Seq.distinctBy (fun foo -> foo.Bar)
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { { Bar = 1 }; { Bar = 2 }; { Bar = 3 } }</c>
    /// </example>
    [<CompiledName("DistinctBy")>]
    val distinctBy: projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> when 'Key : equality

    /// <summary>Splits the input sequence into at most <c>count</c> chunks.</summary>
    ///
    /// <remarks>This function returns a sequence that digests the whole initial sequence as soon as that
    /// sequence is iterated. As a result this function should not be used with large or infinite sequences.</remarks>
    ///
    /// <param name="count">The maximum number of chunks.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The sequence split into chunks.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when <c>count</c> is not positive.</exception>
    ///
    /// <remarks>This function consumes the whole input sequence before yielding the first element of the result sequence.</remarks>
    ///
    /// <example id="split-into-1">
    /// <code lang="fsharp">
    /// let inputs = [1; 2; 3; 4; 5]
    ///
    /// inputs |> Seq.splitInto 3
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { [|1; 2|]; [|3; 4|]; [|5|] }</c>
    /// </example>
    ///
    /// <example id="split-into-2">
    /// <code lang="fsharp">
    /// let inputs = [1; 2; 3; 4; 5]
    ///
    /// inputs |> Seq.splitInto -1
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("SplitInto")>]
    val splitInto: count:int -> source:seq<'T> -> seq<'T[]>

    /// <summary>Creates an empty sequence.</summary>
    ///
    /// <returns>An empty sequence.</returns>
    ///
    /// <example id="empty">
    /// <code lang="fsharp">
    /// Seq.empty // Evaluates to seq { }
    /// </code>
    /// </example>
    [<GeneralizableValue>]
    [<CompiledName("Empty")>]
    val empty<'T> : seq<'T>

    /// <summary>Returns a new sequence with the distinct elements of the second sequence which do not appear in the first sequence,
    /// using generic hash and equality comparisons to compare values.</summary>
    ///
    /// <remarks>Note that this function returns a sequence that digests the whole of the first input sequence as soon as
    /// the result sequence is iterated. As a result this function should not be used with
    /// large or infinite sequences in the first parameter. The function makes no assumption on the ordering of the first input
    /// sequence.</remarks>
    ///
    /// <param name="itemsToExclude">A sequence whose elements that also occur in the second sequence will cause those elements to be
    /// removed from the returned sequence.</param>
    /// <param name="source">A sequence whose elements that are not also in first will be returned.</param>
    ///
    /// <returns>A sequence that contains the set difference of the elements of two sequences.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the two input sequences is null.</exception>
    ///
    /// <example id="except-1">
    /// <code lang="fsharp">
    /// let original = [1; 2; 3; 4; 5]
    /// let itemsToExclude = [1; 3; 5]
    ///
    /// original |> Seq.except itemsToExclude
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 2; 4 }</c>
    /// </example>
    [<CompiledName("Except")>]
    val except: itemsToExclude:seq<'T> -> source:seq<'T> -> seq<'T> when 'T : equality

    /// <summary>Tests if any element of the sequence satisfies the given predicate.</summary>
    ///
    /// <remarks>The predicate is applied to the elements of the input sequence. If any application
    /// returns true then the overall result is true and no further elements are tested.
    /// Otherwise, false is returned.</remarks>
    ///
    /// <param name="predicate">A function to test each item of the input sequence.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>True if any result from the predicate is true; false otherwise.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="exists-1">
    /// <code lang="fsharp">
    /// let input = [1; 2; 3; 4; 5]
    ///
    /// input |> Seq.exists (fun elm -> elm % 4 = 0)
    /// </code>
    /// Evaluates to <c>true</c>
    /// </example>
    ///
    /// <example id="exists-2">
    /// <code lang="fsharp">
    /// let input = [1; 2; 3; 4; 5]
    ///
    /// input |> Seq.exists (fun elm -> elm % 6 = 0)
    /// </code>
    /// Evaluates to <c>false</c>
    /// </example>
    [<CompiledName("Exists")>]
    val exists: predicate:('T -> bool) -> source:seq<'T> -> bool

    /// <summary>Tests if any pair of corresponding elements of the input sequences satisfies the given predicate.</summary>
    ///
    /// <remarks>The predicate is applied to matching elements in the two sequences up to the lesser of the
    /// two lengths of the collections. If any application returns true then the overall result is
    /// true and no further elements are tested. Otherwise, false is returned. If one sequence is shorter than
    /// the other then the remaining elements of the longer sequence are ignored.</remarks>
    ///
    /// <param name="predicate">A function to test each pair of items from the input sequences.</param>
    /// <param name="source1">The first input sequence.</param>
    /// <param name="source2">The second input sequence.</param>
    ///
    /// <returns>True if any result from the predicate is true; false otherwise.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the two input sequences is null.</exception>
    ///
    /// <example id="exists2-1">
    /// <code lang="fsharp">
    /// let inputs1 = [1; 2]
    /// let inputs2 = [1; 2; 0]
    ///
    /// (inputs1, inputs2) ||> Seq.exists2 (fun a b -> a > b)
    /// </code>
    /// Evaluates to <c>false</c>
    /// </example>
    ///
    /// <example id="exists2-2">
    /// <code lang="fsharp">
    /// let inputs1 = [1; 4]
    /// let inputs2 = [1; 3; 5]
    ///
    /// (inputs1, inputs2) ||> Seq.exists2 (fun a b -> a > b)
    /// </code>
    /// Evaluates to <c>true</c>
    /// </example>
    [<CompiledName("Exists2")>]
    val exists2: predicate:('T1 -> 'T2 -> bool) -> source1:seq<'T1> -> source2:seq<'T2> -> bool

    /// <summary>Returns a new collection containing only the elements of the collection
    /// for which the given predicate returns "true". This is a synonym for Seq.where.</summary>
    ///
    /// <remarks>The returned sequence may be passed between threads safely. However,
    /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently.
    ///
    /// Remember sequence is lazy, effects are delayed until it is enumerated.</remarks>
    ///
    /// <param name="predicate">A function to test whether each item in the input sequence should be included in the output.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="filter-1">
    /// <code lang="fsharp">
    /// let inputs = [1; 2; 3; 4]
    ///
    /// inputs |> Seq.filter (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 2; 4 }</c>
    /// </example>
    [<CompiledName("Filter")>]
    val filter: predicate:('T -> bool) -> source:seq<'T> -> seq<'T>

    /// <summary>Returns a new collection containing only the elements of the collection
    /// for which the given predicate returns "true".</summary>
    ///
    /// <remarks>The returned sequence may be passed between threads safely. However,
    /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently.
    ///
    /// Remember sequence is lazy, effects are delayed until it is enumerated.
    ///
    /// A synonym for Seq.filter.</remarks>
    ///
    /// <param name="predicate">A function to test whether each item in the input sequence should be included in the output.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="where-1">
    /// <code lang="fsharp">
    /// [1; 2; 3; 4] |> Seq.where (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 2; 4 }</c>
    /// </example>
    [<CompiledName("Where")>]
    val where: predicate:('T -> bool) -> source:seq<'T> -> seq<'T>

    /// <summary>Returns the first element for which the given function returns True.</summary>
    ///
    /// <param name="predicate">A function to test whether an item in the sequence should be returned.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The first element for which the predicate returns True.</returns>
    ///
    /// <exception cref="T:System.Collections.Generic.KeyNotFoundException">Thrown if no element returns true when
    /// evaluated by the predicate</exception>
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null</exception>
    ///
    /// <example id="find-1">
    /// <code lang="fsharp">
    /// let inputs = [1; 2; 3]
    ///
    /// inputs |> Seq.find (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>2</c>
    /// </example>
    ///
    /// <example id="find-2">
    /// <code lang="fsharp">
    /// let inputs = [1; 2; 3]
    ///
    /// inputs |> Seq.find (fun elm -> elm % 6 = 0)
    /// </code>
    /// Throws <c>KeyNotFoundException</c>
    /// </example>
    [<CompiledName("Find")>]
    val find: predicate:('T -> bool) -> source:seq<'T> -> 'T

    /// <summary>Returns the last element for which the given function returns True.</summary>
    ///
    /// <remarks>This function digests the whole initial sequence as soon as it is called. As a
    /// result this function should not be used with large or infinite sequences.</remarks>
    ///
    /// <param name="predicate">A function to test whether an item in the sequence should be returned.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The last element for which the predicate returns True.</returns>
    ///
    /// <exception cref="T:System.Collections.Generic.KeyNotFoundException">Thrown if no element returns true when
    /// evaluated by the predicate</exception>
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null</exception>
    ///
    /// <example id="find-back-1">
    /// <code lang="fsharp">
    /// let inputs = [2; 3; 4]
    ///
    /// inputs |> Seq.findBack (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>4</c>
    /// </example>
    ///
    /// <example id="find-back-2">
    /// <code lang="fsharp">
    /// let inputs = [2; 3; 4]
    ///
    /// inputs |> Seq.findBack (fun elm -> elm % 6 = 0)
    /// </code>
    /// Throws <c>KeyNotFoundException</c>
    /// </example>
    [<CompiledName("FindBack")>]
    val findBack: predicate:('T -> bool) -> source:seq<'T> -> 'T

    /// <summary>Returns the index of the first element for which the given function returns True.</summary>
    ///
    /// <param name="predicate">A function to test whether the index of a particular element should be returned.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The index of the first element for which the predicate returns True.</returns>
    ///
    /// <exception cref="T:System.Collections.Generic.KeyNotFoundException">Thrown if no element returns true when
    /// evaluated by the predicate</exception>
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null</exception>
    ///
    /// <example id="find-index-1">
    /// <code lang="fsharp">
    /// let inputs = [1; 2; 3; 4; 5]
    ///
    /// inputs |> Seq.findIndex (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>1</c>
    /// </example>
    ///
    /// <example id="find-index-2">
    /// <code lang="fsharp">
    /// let inputs = [1; 2; 3; 4; 5]
    /// inputs |> Seq.findIndex (fun elm -> elm % 6 = 0)
    /// </code>
    /// Throws <c>KeyNotFoundException</c>
    /// </example>
    [<CompiledName("FindIndex")>]
    val findIndex: predicate:('T -> bool) -> source:seq<'T> -> int

    /// <summary>Returns the index of the last element for which the given function returns True.</summary>
    ///
    /// <remarks>This function digests the whole initial sequence as soon as it is called. As a
    /// result this function should not be used with large or infinite sequences.</remarks>
    ///
    /// <param name="predicate">A function to test whether the index of a particular element should be returned.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The index of the last element for which the predicate returns True.</returns>
    ///
    /// <exception cref="T:System.Collections.Generic.KeyNotFoundException">Thrown if no element returns true when
    /// evaluated by the predicate</exception>
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null</exception>
    ///
    /// <example id="find-index-1">
    /// <code lang="fsharp">
    /// let input = [1; 2; 3; 4; 5]
    ///
    /// input |> Seq.findIndex (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>3</c>
    /// </example>
    ///
    /// <example id="find-index-back-2">
    /// <code lang="fsharp">
    /// let input = [1; 2; 3; 4; 5]
    ///
    /// input |> Seq.findIndex (fun elm -> elm % 6 = 0)
    /// </code>
    /// Throws <c>KeyNotFoundException</c>
    /// </example>
    [<CompiledName("FindIndexBack")>]
    val findIndexBack: predicate:('T -> bool) -> source:seq<'T> -> int

    /// <summary>Applies a function to each element of the collection, threading an accumulator argument
    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c>
    /// then computes <c>f (... (f s i0)...) iN</c></summary>
    ///
    /// <param name="folder">A function that updates the state with each element from the sequence.</param>
    /// <param name="state">The initial state.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The state object after the folding function is applied to each element of the sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="fold-1">
    /// <code lang="fsharp">
    /// type Charge =
    ///     | In of int
    ///     | Out of int
    ///
    /// let inputs = [In 1; Out 2; In 3]
    ///
    /// (0, inputs) ||> Seq.fold (fun acc charge ->
    ///     match charge with
    ///     | In i -> acc + i
    ///     | Out o -> acc - o)
    /// </code>
    /// Evaluates to <c>2</c>
    /// </example>
    [<CompiledName("Fold")>]
    val fold<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> source:seq<'T> -> 'State

    /// <summary>Applies a function to corresponding elements of two collections, threading an accumulator argument
    /// through the computation.</summary>
    ///
    /// <remarks> The two sequences need not have equal lengths:
    /// when one sequence is exhausted any remaining elements in the other sequence are ignored.
    /// If the input function is <c>f</c> and the elements are <c>i0...iN</c> and <c>j0...jN</c>
    /// then computes <c>f (... (f s i0 j0)...) iN jN</c>.</remarks>
    ///
    /// <param name="folder">The function to update the state given the input elements.</param>
    /// <param name="state">The initial state.</param>
    /// <param name="source1">The first input sequence.</param>
    /// <param name="source2">The second input sequence.</param>
    ///
    /// <returns>The final state value.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the either of the input sequences is null.</exception>
    ///
    /// <example id="fold2-1">
    /// <code lang="fsharp">
    /// type CoinToss = Head | Tails
    ///
    /// let data1 = [Tails; Head; Tails]
    /// let data2 = [Tails; Head; Head]
    ///
    /// (0, data1, data2) |||> Seq.fold2 (fun acc a b ->
    ///     match (a, b) with
    ///     | Head, Head -> acc + 1
    ///     | Tails, Tails -> acc + 1
    ///     | _ -> acc - 1)
    /// </code>
    /// Evaluates to <c>1</c>
    /// </example>
    [<CompiledName("Fold2")>]
    val fold2<'T1,'T2,'State> : folder:('State -> 'T1 -> 'T2 -> 'State) -> state:'State -> source1:seq<'T1> -> source2:seq<'T2> -> 'State

    /// <summary>Applies a function to each element of the collection, starting from the end, threading an accumulator argument
    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c>
    /// then computes <c>f i0 (... (f iN s)...)</c></summary>
    ///
    /// <param name="folder">The function to update the state given the input elements.</param>
    /// <param name="source">The input sequence.</param>
    /// <param name="state">The initial state.</param>
    ///
    /// <returns>The state object after the folding function is applied to each element of the sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <remarks>This function consumes the whole input sequence before returning the result.</remarks>
    ///
    /// <example id="foldback-1">
    /// <code lang="fsharp">
    /// type Count =
    ///   { Positive: int
    ///     Negative: int
    ///     Text: string }
    ///
    /// let sequence = [1; 0; -1; -2; 3]
    /// let initialState = {Positive = 0; Negative = 0; Text = ""}
    ///
    /// (sequence, initialState) ||> Seq.foldBack (fun a acc  ->
    ///     let text = acc.Text + " " + string a
    ///     if a >= 0 then
    ///         { acc with
    ///             Positive = acc.Positive + 1
    ///             Text = text }
    ///     else
    ///         { acc with
    ///             Negative = acc.Negative + 1
    ///             Text = text })
    /// </code>
    /// Evaluates to
    /// <code>
    /// { Positive = 2
    ///   Negative = 3
    ///   Text = " 3 -2 -1 0 1" }
    /// </code>
    /// </example>
    [<CompiledName("FoldBack")>]
    val foldBack<'T,'State> : folder:('T -> 'State -> 'State) -> source:seq<'T> -> state:'State -> 'State

    /// <summary>Applies a function to corresponding elements of two collections, starting from the end of the shorter collection,
    /// threading an accumulator argument through the computation. The two sequences need not have equal lengths.
    /// If the input function is <c>f</c> and the elements are <c>i0...iN</c> and <c>j0...jM</c>, N &lt; M
    /// then computes <c>f i0 j0 (... (f iN jN s)...)</c>.</summary>
    ///
    /// <param name="folder">The function to update the state given the input elements.</param>
    /// <param name="source1">The first input sequence.</param>
    /// <param name="source2">The second input sequence.</param>
    /// <param name="state">The initial state.</param>
    ///
    /// <returns>The final state value.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the either of the input sequences is null.</exception>
    ///
    /// <remarks>
    /// This function consumes the whole of both inputs sequences before returning the result. As a
    /// result this function should not be used with large or infinite sequences.
    /// </remarks>
    ///
    /// <example id="foldback2-1">
    /// <code lang="fsharp">
    /// type Count =
    ///   { Positive: int
    ///     Negative: int
    ///     Text: string }
    ///
    /// let inputs1 = [-1; -2; -3]
    /// let inputs2 = [3; 2; 1; 0]
    /// let initialState = {Positive = 0; Negative = 0; Text = ""}
    ///
    /// (inputs1, inputs2, initialState) |||> Seq.foldBack2 (fun a b acc  ->
    ///     let text = acc.Text + "(" + string a + "," + string b + ") "
    ///     if a + b >= 0 then
    ///         { acc with
    ///             Positive = acc.Positive + 1
    ///             Text = text }
    ///     else
    ///         { acc with
    ///             Negative = acc.Negative + 1
    ///             Text = text }
    /// )
    /// </code>
    /// Evaluates to
    /// <code>
    /// { Positive = 2
    ///   Negative = 1
    ///   Text = " (-3,1) (-2,2) (-1,3)" }
    /// </code>
    /// </example>
    [<CompiledName("FoldBack2")>]
    val foldBack2<'T1,'T2,'State> : folder:('T1 -> 'T2 -> 'State -> 'State) -> source1:seq<'T1> -> source2:seq<'T2> -> state:'State -> 'State

    /// <summary>Tests if all elements of the sequence satisfy the given predicate.</summary>
    ///
    /// <remarks>The predicate is applied to the elements of the input sequence. If any application
    /// returns false then the overall result is false and no further elements are tested.
    /// Otherwise, true is returned.</remarks>
    ///
    /// <param name="predicate">A function to test an element of the input sequence.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>True if every element of the sequence satisfies the predicate; false otherwise.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="forall-1">
    /// <code lang="fsharp">
    /// let isEven a = a % 2 = 0
    ///
    /// [2; 42] |> Seq.forall isEven // evaluates to true
    ///
    /// [1; 2] |> Seq.forall isEven // evaluates to false
    /// </code>
    /// </example>
    [<CompiledName("ForAll")>]
    val forall: predicate:('T -> bool) -> source:seq<'T> -> bool

    /// <summary>Tests the all pairs of elements drawn from the two sequences satisfy the
    /// given predicate. If one sequence is shorter than
    /// the other then the remaining elements of the longer sequence are ignored.</summary>
    ///
    /// <param name="predicate">A function to test pairs of elements from the input sequences.</param>
    /// <param name="source1">The first input sequence.</param>
    /// <param name="source2">The second input sequence.</param>
    ///
    /// <returns>True if all pairs satisfy the predicate; false otherwise.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input sequences is null.</exception>
    ///
    /// <example id="forall2-1">
    /// <code lang="fsharp">
    /// let inputs1 = [1; 2; 3; 4; 5; 6]
    /// let inputs2 = [1; 2; 3; 4; 5]
    ///
    /// (inputs1, inputs2)  ||> Seq.forall2 (=)
    /// </code>
    /// Evaluates to <c>true</c>.
    /// </example>
    ///
    /// <example id="forall2-2">
    /// <code lang="fsharp">
    /// let items1 = [2017; 1; 1]
    /// let items2 = [2019; 19; 8]
    ///
    /// (items1, items2) ||> Seq.forall2 (=)
    /// </code>
    /// Evaluates to <c>false</c>.
    /// </example>
    [<CompiledName("ForAll2")>]
    val forall2: predicate:('T1 -> 'T2 -> bool) -> source1:seq<'T1> -> source2:seq<'T2> -> bool

    /// <summary>Applies a key-generating function to each element of a sequence and yields a sequence of
    /// unique keys. Each unique key contains a sequence of all elements that match
    /// to this key.</summary>
    ///
    /// <remarks>This function returns a sequence that digests the whole initial sequence as soon as
    /// that sequence is iterated. As a result this function should not be used with
    /// large or infinite sequences. The function makes no assumption on the ordering of the original
    /// sequence.</remarks>
    ///
    /// <param name="projection">A function that transforms an element of the sequence into a comparable key.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <example id="group-by-1">
    /// <code lang="fsharp">
    /// let inputs = [1; 2; 3; 4; 5]
    ///
    /// inputs |> Seq.groupBy (fun n -> n % 2)
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { (1, seq { 1; 3; 5 }); (0, seq { 2; 4 }) }</c>
    /// </example>
    [<CompiledName("GroupBy")>]
    val groupBy: projection:('T -> 'Key) -> source:seq<'T> -> seq<'Key * seq<'T>> when 'Key : equality

    /// <summary>Returns the first element of the sequence.</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The first element of the sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input does not have any elements.</exception>
    ///
    /// <example id="head-1">
    /// <code lang="fsharp">
    /// let inputs = ["banana"; "pear"]
    ///
    /// inputs |> Seq.head
    /// </code>
    /// Evaluates to <c>banana</c>
    /// </example>
    ///
    /// <example id="head-2">
    /// <code lang="fsharp">
    /// [] |> Seq.head
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("Head")>]
    val head: source:seq<'T> -> 'T

    /// <summary>Returns the first element of the sequence, or None if the sequence is empty.</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The first element of the sequence or None.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="try-head-1">
    /// <code lang="fsharp">
    /// ["banana"; "pear"] |> Seq.tryHead
    /// </code>
    /// Evaluates to <c>Some "banana"</c>
    /// </example>
    ///
    /// <example id="try-head-2">
    /// <code lang="fsharp">
    /// [] |> Seq.tryHead
    /// </code>
    /// Evaluates to <c>None</c>
    /// </example>
    [<CompiledName("TryHead")>]
    val tryHead: source:seq<'T> -> 'T option

    /// <summary>Returns the last element of the sequence.</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The last element of the sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input does not have any elements.</exception>
    ///
    /// <example id="last-1">
    /// <code lang="fsharp">
    /// ["pear"; "banana"] |> Seq.last
    /// </code>
    /// Evaluates to <c>banana</c>
    /// </example>
    ///
    /// <example id="last-2">
    /// <code lang="fsharp">
    /// [] |> Seq.last
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("Last")>]
    val last: source:seq<'T> -> 'T

    /// <summary>Returns the last element of the sequence.
    /// Return <c>None</c> if no such element exists.</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The last element of the sequence or None.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="try-last-1">
    /// <code lang="fsharp">
    /// ["pear"; "banana"] |> Seq.tryLast
    /// </code>
    /// Evaluates to <c>Some "banana"</c>
    /// </example>
    ///
    /// <example id="try-last-2">
    /// <code lang="fsharp">
    /// [] |> Seq.tryLast
    /// </code>
    /// Evaluates to <c>None</c>
    /// </example>
    [<CompiledName("TryLast")>]
    val tryLast: source:seq<'T> -> 'T option

    /// <summary>Returns the only element of the sequence.</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The only element of the sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input does not have precisely one element.</exception>
    ///
    /// <example id="exacly-one-1">
    /// <code lang="fsharp">
    /// let inputs = ["banana"]
    ///
    /// inputs |> Seq.exactlyOne
    /// </code>
    /// Evaluates to <c>banana</c>
    /// </example>
    ///
    /// <example id="exacly-one-2">
    /// <code lang="fsharp">
    /// let inputs = ["pear"; "banana"]
    ///
    /// inputs |> Seq.exactlyOne
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    ///
    /// <example id="exacly-one-3">
    /// <code lang="fsharp">
    /// [] |> Seq.exactlyOne
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("ExactlyOne")>]
    val exactlyOne: source:seq<'T> -> 'T

    /// <summary>Returns the only element of the sequence or <c>None</c> if sequence is empty or contains more than one element.</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The only element of the sequence or None.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="try-exacly-one-1">
    /// <code lang="fsharp">
    /// let inputs = ["banana"]
    ///
    /// inputs |> Seq.tryExactlyOne
    /// </code>
    /// Evaluates to <c>Some banana</c>
    /// </example>
    ///
    /// <example id="try-exacly-one-2">
    /// <code lang="fsharp">
    /// let inputs = ["pear"; "banana"]
    ///
    /// inputs |> Seq.tryExactlyOne
    /// </code>
    /// Evaluates to <c>None</c>
    /// </example>
    ///
    /// <example id="try-exacly-one-3">
    /// <code lang="fsharp">
    /// [] |> Seq.tryExactlyOne
    /// </code>
    /// Evaluates to <c>None</c>
    /// </example>
    [<CompiledName("TryExactlyOne")>]
    val tryExactlyOne: source:seq<'T> -> 'T option

    /// <summary>Returns true if the sequence contains no elements, false otherwise.</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>True if the sequence is empty; false otherwise.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="empty-1">
    /// <code lang="fsharp">
    /// [] |> Seq.isEmpty
    /// </code>
    /// Evaluates to <c>true</c>
    /// </example>
    ///
    /// <example id="empty-2">
    /// <code lang="fsharp">
    /// ["pear"; "banana"] |> Seq.isEmpty
    /// </code>
    /// Evaluates to <c>false</c>
    /// </example>
    [<CompiledName("IsEmpty")>]
    val isEmpty: source:seq<'T> -> bool

    /// <summary>Builds a new collection whose elements are the corresponding elements of the input collection
    /// paired with the integer index (from 0) of each element.</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="indexed-1">
    /// <code lang="fsharp">
    /// ["a"; "b"; "c"] |> Seq.indexed
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { (0, "a"); (1, "b"); (2, "c") }</c>
    /// </example>
    [<CompiledName("Indexed")>]
    val indexed: source:seq<'T> -> seq<int * 'T>

    /// <summary>Generates a new sequence which, when iterated, will return successive
    /// elements by calling the given function, up to the given count.  Each element is saved after its
    /// initialization.  The function is passed the index of the item being
    /// generated.</summary>
    ///
    /// <remarks>The returned sequence may be passed between threads safely. However,
    /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently.</remarks>
    ///
    /// <param name="count">The maximum number of items to generate for the sequence.</param>
    /// <param name="initializer">A function that generates an item in the sequence from a given index.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when count is negative.</exception>
    ///
    /// <example id="init-1">
    /// <code lang="fsharp">
    /// Seq.init 4 (fun v -> v + 5)
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 5; 6; 7; 8 }</c>
    /// </example>
    ///
    /// <example id="init-2">
    /// <code lang="fsharp">
    /// Seq.init -5 (fun v -> v + 5)
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("Initialize")>]
    val init: count:int -> initializer:(int -> 'T) -> seq<'T>

    /// <summary>Generates a new sequence which, when iterated, will return successive
    /// elements by calling the given function.  The results of calling the function
    /// will not be saved, that is the function will be reapplied as necessary to
    /// regenerate the elements.  The function is passed the index of the item being
    /// generated.</summary>
    ///
    /// <remarks>The returned sequence may be passed between threads safely. However,
    /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently.
    /// Iteration can continue up to <c>Int32.MaxValue</c>.</remarks>
    ///
    /// <param name="initializer">A function that generates an item in the sequence from a given index.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <example id="init-infinite-1">
    /// <code lang="fsharp">
    /// (+) 5 |> Seq.initInfinite
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 5; 6; 7; 8; ... }</c>
    /// </example>
    [<CompiledName("InitializeInfinite")>]
    val initInfinite: initializer:(int -> 'T) -> seq<'T>

    /// <summary>Computes the element at the specified index in the collection.</summary>
    ///
    /// <param name="index">The index of the element to retrieve.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The element at the specified index of the sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the index is negative or the input sequence does not contain enough elements.</exception>
    ///
    /// <example id="item-1">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "b"; "c"]
    ///
    /// inputs |> Seq.item 1
    /// </code>
    /// Evaluates to <c>"b"</c>
    /// </example>
    ///
    /// <example id="item-2">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "b"; "c"]
    ///
    /// inputs |> Seq.item 4
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("Item")>]
    val item: index:int -> source:seq<'T> -> 'T

    /// <summary>Applies the given function to each element of the collection.</summary>
    ///
    /// <param name="action">A function to apply to each element of the sequence.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="iter-1">
    /// <code lang="fsharp">
    /// ["a"; "b"; "c"] |> Seq.iter (printfn "%s")
    /// </code>
    /// Evaluates to <c>unit</c> and prints
    /// <code>
    /// a
    /// b
    /// c
    /// </code>
    /// in the console.
    /// </example>
    [<CompiledName("Iterate")>]
    val iter: action:('T -> unit) -> source:seq<'T> -> unit

    /// <summary>Applies the given function to each element of the collection. The integer passed to the
    /// function indicates the index of element.</summary>
    ///
    /// <param name="action">A function to apply to each element of the sequence that can also access the current index.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="iteri-1">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "b"; "c"]
    ///
    /// inputs |> Seq.iteri (fun i v -> printfn "{i}: {v}")
    ///
    /// </code>
    /// Evaluates to <c>unit</c> and prints
    /// <code>
    /// 0: a
    /// 1: b
    /// 2: c
    /// </code>
    /// in the console.
    /// </example>
    [<CompiledName("IterateIndexed")>]
    val iteri: action:(int -> 'T -> unit) -> source:seq<'T> -> unit

    /// <summary>Applies the given function to two collections simultaneously. If one sequence is shorter than
    /// the other then the remaining elements of the longer sequence are ignored.</summary>
    ///
    /// <param name="action">A function to apply to each pair of elements from the input sequences.</param>
    /// <param name="source1">The first input sequence.</param>
    /// <param name="source2">The second input sequence.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input sequences is null.</exception>
    ///
    /// <example id="iter2-1">
    /// <code lang="fsharp">
    /// let inputs1 = ["a"; "b"; "c"]
    /// let inputs2 = [1; 2; 3]
    ///
    /// (inputs1, inputs2) ||> Seq.iter2 (printfn "%s: %i")
    /// </code>
    /// Evaluates to <c>unit</c> and prints
    /// <code>
    /// a: 1
    /// b: 2
    /// c: 3
    /// </code>
    /// in the console.
    /// </example>
    [<CompiledName("Iterate2")>]
    val iter2: action:('T1 -> 'T2 -> unit) -> source1:seq<'T1> -> source2:seq<'T2> -> unit

    /// <summary>Applies the given function to two collections simultaneously. If one sequence is shorter than
    /// the other then the remaining elements of the longer sequence are ignored. The integer passed to the
    /// function indicates the index of element.</summary>
    ///
    /// <param name="action">A function to apply to each pair of elements from the input sequences along with their index.</param>
    /// <param name="source1">The first input sequence.</param>
    /// <param name="source2">The second input sequence.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input sequences is null.</exception>
    ///
    /// <example id="iteri2-1">
    /// <code lang="fsharp">
    /// let inputs1 = ["a"; "b"; "c"]
    /// let inputs2 = ["banana"; "pear"; "apple"]
    ///
    /// (inputs1, inputs2) ||> Seq.iteri2 (fun i s1 s2 -> printfn "Index {i}: {s1} - {s2}")
    /// </code>
    /// Evaluates to <c>unit</c> and prints
    /// <code>
    /// Index 0: a - banana
    /// Index 1: b - pear
    /// Index 2: c - apple
    /// </code>
    /// in the console.
    /// </example>
    [<CompiledName("IterateIndexed2")>]
    val iteri2: action:(int -> 'T1 -> 'T2 -> unit) -> source1:seq<'T1> -> source2:seq<'T2> -> unit

    /// <summary>Returns the length of the sequence</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The length of the sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="item-1">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "b"; "c"]
    ///
    /// inputs |> Seq.length
    /// </code>
    /// Evaluates to <c>3</c>
    /// </example>
    [<CompiledName("Length")>]
    val length: source:seq<'T> -> int

    /// <summary>Builds a new collection whose elements are the results of applying the given function
    /// to each of the elements of the collection.  The given function will be applied
    /// as elements are demanded using the <c>MoveNext</c> method on enumerators retrieved from the
    /// object.</summary>
    ///
    /// <remarks>The returned sequence may be passed between threads safely. However,
    /// individual IEnumerator values generated from the returned sequence should not be accessed concurrently.</remarks>
    ///
    /// <param name="mapping">A function to transform items from the input sequence.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="item-1">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "bbb"; "cc"]
    ///
    /// inputs |> Seq.map (fun x -> x.Length)
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 1; 3; 2 }</c>
    /// </example>
    [<CompiledName("Map")>]
    val map: mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>

    /// <summary>Builds a new collection whose elements are the results of applying the given function
    /// to the corresponding pairs of elements from the two sequences. If one input sequence is shorter than
    /// the other then the remaining elements of the longer sequence are ignored.</summary>
    ///
    /// <param name="mapping">A function to transform pairs of items from the input sequences.</param>
    /// <param name="source1">The first input sequence.</param>
    /// <param name="source2">The second input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input sequences is null.</exception>
    ///
    /// <example id="item-1">
    /// <code lang="fsharp">
    /// let inputs1 = ["a"; "bad"; "good"]
    /// let inputs2 = [0; 2; 1]
    ///
    /// (inputs1, inputs2) ||> Seq.map2 (fun x y -> x.[y])
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 'a'; 'd'; 'o' }</c>
    /// </example>
    [<CompiledName("Map2")>]
    val map2: mapping:('T1 -> 'T2 -> 'U) -> source1:seq<'T1> -> source2:seq<'T2> -> seq<'U>

    /// <summary>Combines map and fold. Builds a new collection whose elements are the results of applying the given function
    /// to each of the elements of the collection. The function is also used to accumulate a final value.</summary>
    ///
    /// <remarks>This function digests the whole initial sequence as soon as it is called. As a result this function should
    /// not be used with large or infinite sequences.</remarks>
    ///
    /// <param name="mapping">The function to transform elements from the input collection and accumulate the final value.</param>
    /// <param name="state">The initial state.</param>
    /// <param name="source">The input collection.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input collection is null.</exception>
    ///
    /// <returns>The collection of transformed elements, and the final accumulated value.</returns>
    ///
    /// <example id="mapfold-1">
    /// <code lang="fsharp">Accumulate the charges, and double them as well
    /// type Charge =
    ///     | In of int
    ///     | Out of int
    ///
    /// let inputs = seq { In 1; Out 2; In 3 }
    ///
    /// let newCharges, balance =
    ///     (0, inputs) ||> Seq.mapFold (fun acc charge ->
    ///         match charge with
    ///         | In i -> In (i*2), acc + i
    ///         | Out o -> Out (o*2), acc - o)
    /// </code>
    /// Evaluates <c>newCharges</c> to <c>seq { In 2; Out 4; In 6 }</c> and <c>balance</c> to <c>2</c>.
    /// </example>
    [<CompiledName("MapFold")>]
    val mapFold<'T,'State,'Result> : mapping:('State -> 'T -> 'Result * 'State) -> state:'State -> source:seq<'T> -> seq<'Result> * 'State

    /// <summary>Combines map and foldBack. Builds a new collection whose elements are the results of applying the given function
    /// to each of the elements of the collection. The function is also used to accumulate a final value.</summary>
    ///
    /// <remarks>This function digests the whole initial sequence as soon as it is called. As a result this function should
    /// not be used with large or infinite sequences.</remarks>
    ///
    /// <param name="mapping">The function to transform elements from the input collection and accumulate the final value.</param>
    /// <param name="source">The input collection.</param>
    /// <param name="state">The initial state.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input collection is null.</exception>
    ///
    /// <returns>The collection of transformed elements, and the final accumulated value.</returns>
    ///
    /// <example id="mapfold-1">Accumulate the charges from back to front, and double them as well
    /// <code lang="fsharp">
    /// type Charge =
    ///     | In of int
    ///     | Out of int
    ///
    /// let inputs = seq { In 1; Out 2; In 3 }
    ///
    /// let newCharges, balance =
    ///     (inputs, 0) ||> Seq.mapFoldBack (fun charge acc ->
    ///         match charge with
    ///         | In i -> In (i*2), acc + i
    ///         | Out o -> Out (o*2), acc - o)
    /// </code>
    /// Evaluates <c>newCharges</c> to <c>seq { In 2; Out 4; In 6 }</c> and <c>balance</c> to <c>2</c>.
    /// </example>
    [<CompiledName("MapFoldBack")>]
    val mapFoldBack<'T,'State,'Result> : mapping:('T -> 'State -> 'Result * 'State) -> source:seq<'T> -> state:'State -> seq<'Result> * 'State

    /// <summary>Builds a new collection whose elements are the results of applying the given function
    /// to the corresponding triples of elements from the three sequences. If one input sequence if shorter than
    /// the others then the remaining elements of the longer sequences are ignored.</summary>
    ///
    /// <param name="mapping">The function to transform triples of elements from the input sequences.</param>
    /// <param name="source1">The first input sequence.</param>
    /// <param name="source2">The second input sequence.</param>
    /// <param name="source3">The third input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when any of the input sequences is null.</exception>
    ///
    /// <example id="item-1">
    /// <code lang="fsharp">
    /// let inputs1 = [ "a"; "t"; "ti" ]
    /// let inputs2 = [ "l"; "h"; "m" ]
    /// let inputs3 = [ "l"; "e"; "e" ]
    ///
    /// (inputs1, inputs2, inputs3) |||> Seq.map3 (fun x y z -> x + y + z)
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { "all"; "the"; "time" } </c>
    /// </example>
    /// 
    [<CompiledName("Map3")>]
    val map3: mapping:('T1 -> 'T2 -> 'T3 -> 'U) -> source1:seq<'T1> -> source2:seq<'T2> -> source3:seq<'T3> -> seq<'U>

    /// <summary>Builds a new collection whose elements are the results of applying the given function
    /// to each of the elements of the collection. The integer index passed to the
    /// function indicates the index (from 0) of element being transformed.</summary>
    ///
    /// <param name="mapping">A function to transform items from the input sequence that also supplies the current index.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="item-1">
    /// <code lang="fsharp">
    /// let inputs = [ 10; 10; 10 ]
    ///
    /// inputs |> Seq.mapi (fun i x -> i + x)
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 10; 11; 12 }</c>
    /// </example>
    [<CompiledName("MapIndexed")>]
    val mapi: mapping:(int -> 'T -> 'U) -> source:seq<'T> -> seq<'U>

    /// <summary>Builds a new collection whose elements are the results of applying the given function
    /// to the corresponding pairs of elements from the two sequences. If one input sequence is shorter than
    /// the other then the remaining elements of the longer sequence are ignored. The integer index passed to the
    /// function indicates the index (from 0) of element being transformed.</summary>
    ///
    /// <param name="mapping">A function to transform pairs of items from the input sequences that also supplies the current index.</param>
    /// <param name="source1">The first input sequence.</param>
    /// <param name="source2">The second input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input sequences is null.</exception>
    ///
    /// <example id="mapi2-1">
    /// <code lang="fsharp">
    /// let inputs1 = ["a"; "bad"; "good"]
    /// let inputs2 = [0; 2; 1]
    ///
    /// (inputs1, inputs2) ||> Seq.mapi2 (fun i x y -> i, x[y])
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { (0, 'a'); (1, 'd'); (2, 'o') }</c>
    /// </example>
    [<CompiledName("MapIndexed2")>]
    val mapi2: mapping:(int -> 'T1 -> 'T2 -> 'U) -> source1:seq<'T1> -> source2:seq<'T2> -> seq<'U>

    /// <summary>Returns the greatest of all elements of the sequence, compared via Operators.max</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input sequence is empty.</exception>
    ///
    /// <returns>The largest element of the sequence.</returns>
    ///
    /// <example id="max-1">
    /// <code lang="fsharp">
    /// let inputs = [ 10; 12; 11 ]
    ///
    /// inputs |> Seq.max
    /// </code>
    /// Evaluates to <c>12</c>
    /// </example>
    ///
    /// <example id="max-2">
    /// <code lang="fsharp">
    /// let inputs = [ ]
    ///
    /// inputs |> Seq.max
    /// </code>
    /// Throws <c>System.ArgumentException</c>.
    /// </example>
    [<CompiledName("Max")>]
    val inline max: source:seq<'T> -> 'T when 'T : comparison

    /// <summary>Returns the greatest of all elements of the sequence, compared via Operators.max on the function result.</summary>
    ///
    /// <param name="projection">A function to transform items from the input sequence into comparable keys.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The largest element of the sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input sequence is empty.</exception>
    ///
    /// <example id="maxby-1">
    /// <code lang="fsharp">
    /// let inputs = ["aaa"; "b"; "cccc"]
    ///
    /// inputs |> Seq.maxBy (fun s -> s.Length)
    /// </code>
    /// Evaluates to <c>"cccc"</c>
    /// </example>
    ///
    /// <example id="maxby-2">
    /// <code lang="fsharp">
    /// let inputs = [ ]
    ///
    /// inputs |> Seq.maxBy (fun s -> s.Length)
    /// </code>
    /// Throws <c>System.ArgumentException</c>.
    /// </example>
    [<CompiledName("MaxBy")>]
    val inline maxBy  : projection:('T -> 'U) -> source:seq<'T> -> 'T when 'U : comparison

    /// <summary>Returns the lowest of all elements of the sequence, compared via <c>Operators.min</c>.</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The smallest element of the sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input sequence is empty.</exception>
    ///
    /// <example id="min-1">
    /// <code lang="fsharp">
    /// let inputs = [10; 12; 11]
    ///
    /// inputs |> Seq.min
    /// </code>
    /// Evaluates to <c>10</c>
    /// </example>
    ///
    /// <example id="min-2">
    /// <code lang="fsharp">
    /// let inputs = []
    ///
    /// inputs |> Seq.min
    /// </code>
    /// Throws <c>System.ArgumentException</c>.
    /// </example>
    [<CompiledName("Min")>]
    val inline min: source:seq<'T> -> 'T when 'T : comparison

    /// <summary>Returns the lowest of all elements of the sequence, compared via Operators.min on the function result.</summary>
    ///
    /// <param name="projection">A function to transform items from the input sequence into comparable keys.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The smallest element of the sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input sequence is empty.</exception>
    ///
    /// <example id="minby-1">
    /// <code lang="fsharp">
    /// let inputs = [ "aaa"; "b"; "cccc" ]
    ///
    /// inputs |> Seq.minBy (fun s -> s.Length)
    /// </code>
    /// Evaluates to <c>"b"</c>
    /// </example>
    ///
    /// <example id="minby-2">
    /// <code lang="fsharp">
    /// let inputs = []
    ///
    /// inputs |> Seq.minBy (fun (s: string) -> s.Length)
    /// </code>
    /// Throws <c>System.ArgumentException</c>.
    /// </example>
    [<CompiledName("MinBy")>]
    val inline minBy: projection:('T -> 'U) -> source:seq<'T> -> 'T when 'U : comparison

    /// <summary>Computes the nth element in the collection.</summary>
    ///
    /// <param name="index">The index of element to retrieve.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The nth element of the sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the index is negative or the input sequence does not contain enough elements.</exception>
    [<CompiledName("Get")>]
    [<Obsolete("please use Seq.item")>]
    val nth: index:int -> source:seq<'T> -> 'T

    /// <summary>Views the given array as a sequence.</summary>
    ///
    /// <param name="source">The input array.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="ofarray-1">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 5 |]
    ///
    /// inputs |> Seq.ofArray
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 1; 2; 5 }</c>.
    /// </example>
    [<CompiledName("OfArray")>]
    val ofArray: source:'T[] -> seq<'T>

    /// <summary>Views the given list as a sequence.</summary>
    ///
    /// <param name="source">The input list.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <example id="oflist-1">
    /// <code lang="fsharp">
    /// let inputs = [ 1; 2; 5 ]
    ///
    /// inputs |> Seq.ofList
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 1; 2; 5 }</c>.
    /// </example>
    [<CompiledName("OfList")>]
    val ofList: source:'T list -> seq<'T>

    /// <summary>Returns a sequence of each element in the input sequence and its predecessor, with the
    /// exception of the first element which is only returned as the predecessor of the second element.</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// 
    /// <example id="pairwise-1">
    /// <code lang="fsharp">
    /// let inputs = seq { 1; 2; 3; 4 }
    ///
    /// inputs |> Seq.pairwise
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { (1, 2); (2, 3); (3, 4) }</c>.
    /// </example>
    [<CompiledName("Pairwise")>]
    val pairwise: source:seq<'T> -> seq<'T * 'T>

    /// <summary>Returns a sequence with all elements permuted according to the
    /// specified permutation.</summary>
    ///
    /// <remarks>This function consumes the whole input sequence before yielding the first element of the result sequence.</remarks>
    ///
    /// <param name="indexMap">The function that maps input indices to output indices.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when indexMap does not produce a valid permutation.</exception>
    /// 
    /// <example id="permute-1">
    /// <code lang="fsharp">
    /// let inputs = [1; 2; 3; 4]
    ///
    /// inputs |> Seq.permute (fun x -> (x + 1) % 4)
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 4; 1; 2; 3 }</c>.
    /// </example>
    [<CompiledName("Permute")>]
    val permute: indexMap:(int -> int) -> source:seq<'T> -> seq<'T>

    /// <summary>Applies the given function to successive elements, returning the first
    /// <c>x</c> where the function returns "Some(x)".</summary>
    ///
    /// <param name="chooser">A function to transform each item of the input sequence into an option of the output type.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The selected element.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.Collections.Generic.KeyNotFoundException">Thrown when every item of the sequence
    /// evaluates to <c>None</c> when the given function is applied.</exception>
    ///
    /// <example id="pick-1">
    /// <code lang="fsharp">
    /// let input = [1; 2; 3]
    ///
    /// input |> Seq.pick (fun n -> if n % 2 = 0 then Some (string n) else None)
    /// </code>
    /// Evaluates to <c>"2"</c>.
    /// </example>
    ///
    /// <example id="pick-2">
    /// <code lang="fsharp">
    /// let input = [1; 2; 3]
    ///
    /// input |> Seq.pick (fun n -> if n > 3 = 0 then Some (string n) else None)
    /// </code>
    /// Throws <c>KeyNotFoundException</c>.
    /// </example>
    ///
    [<CompiledName("Pick")>]
    val pick: chooser:('T -> 'U option) -> source:seq<'T> -> 'U

    /// <summary>Builds a new sequence object that delegates to the given sequence object. This ensures
    /// the original sequence cannot be rediscovered and mutated by a type cast. For example,
    /// if given an array the returned sequence will return the elements of the array, but
    /// you cannot cast the returned sequence object to an array.</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="readonly-1">
    /// <code lang="fsharp">
    /// let input = [| 1; 2; 3 |]
    ///
    /// input |> Seq.readonly
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 1; 2; 3 }</c>.
    /// </example>
    ///
    /// <example id="readonly-2">
    /// <code lang="fsharp">
    /// let input = [| 1; 2; 3 |]
    ///
    /// let readonlyView = input |> Seq.readonly
    ///
    /// (readonlyView :?> int[]).[1] &lt;- 4
    /// </code>
    /// Throws an <c>InvalidCastException</c>.
    /// </example>
    [<CompiledName("ReadOnly")>]
    val readonly: source:seq<'T> -> seq<'T>

    /// <summary>Applies a function to each element of the sequence, threading an accumulator argument
    /// through the computation. Begin by applying the function to the first two elements.
    /// Then feed this result into the function along with the third element and so on.
    /// Return the final result.</summary>
    ///
    /// <param name="reduction">A function that takes in the current accumulated result and the next
    /// element of the sequence to produce the next accumulated result.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The final result of the reduction function.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input sequence is empty.</exception>
    /// 
    /// <example id="reduce-1">
    /// <code lang="fsharp">
    /// let inputs = [1; 3; 4; 2]
    ///
    /// inputs |> Seq.reduce (fun a b -> a * 10 + b)
    /// </code>
    /// Evaluates to <c>1342</c>, by computing <c>((1 * 10 + 3) * 10 + 4) * 10 + 2</c>
    /// </example>
    [<CompiledName("Reduce")>]
    val reduce: reduction:('T -> 'T -> 'T) -> source:seq<'T> -> 'T

    /// <summary>Creates a sequence by replicating the given initial value.</summary>
    ///
    /// <param name="count">The number of elements to replicate.</param>
    /// <param name="initial">The value to replicate</param>
    ///
    /// <returns>The generated sequence.</returns>
    /// 
    /// <example id="replicate-1">
    /// <code lang="fsharp">
    /// Seq.replicate 3 "a"
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { "a"; "a"; "a" }</c>.
    /// </example>
    [<CompiledName("Replicate")>]
    val replicate: count:int -> initial:'T -> seq<'T>

    /// <summary>Applies a function to each element of the sequence, starting from the end, threading an accumulator argument
    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c>
    /// then computes <c>f i0 (...(f iN-1 iN))</c>.</summary>
    ///
    /// <param name="reduction">A function that takes in the next-to-last element of the sequence and the
    /// current accumulated result to produce the next accumulated result.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The final result of the reductions.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input sequence is empty.</exception>
    ///
    /// <remarks>This function consumes the whole input sequence before returning the result.</remarks>
    /// 
    /// <example id="reduceback-1">
    /// <code lang="fsharp">
    /// let inputs = [1; 3; 4; 2]
    ///
    /// inputs |> Seq.reduceBack (fun a b -> a + b * 10)
    /// </code>
    /// Evaluates to <c>2431</c>, by computing <c>1 + (3 + (4 + 2 * 10) * 10) * 10</c>
    /// </example>
    [<CompiledName("ReduceBack")>]
    val reduceBack: reduction:('T -> 'T -> 'T) -> source:seq<'T> -> 'T

    /// <summary>Returns a new sequence with the elements in reverse order.</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The reversed sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <remarks>This function consumes the whole input sequence before yielding the first element of the reversed sequence.</remarks>
    /// 
    /// <example id="rev-1">
    /// <code lang="fsharp">
    /// let input = seq { 0; 1; 2 }
    ///
    /// input |> Seq.rev
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 2; 1; 0 }</c>.
    /// </example>
    [<CompiledName("Reverse")>]
    val rev: source:seq<'T> -> seq<'T>

    /// <summary>Like fold, but computes on-demand and returns the sequence of intermediary and final results.</summary>
    ///
    /// <param name="folder">A function that updates the state with each element from the sequence.</param>
    /// <param name="state">The initial state.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The resulting sequence of computed states.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// 
    /// <example id="scan-1">Apply a list charges and collect the running balances as each is applied:
    /// <code lang="fsharp">
    /// type Charge =
    ///     | In of int
    ///     | Out of int
    ///
    /// let inputs = seq { In 1; Out 2; In 3 }
    ///
    /// (0, inputs) ||> Seq.scan (fun acc charge ->
    ///     match charge with
    ///     | In i -> acc + i
    ///     | Out o -> acc - o)
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 0; 1; -1; 2 }</c>. Note <c>0</c> is the intial
    /// state, <c>1</c> the next state, <c>-1</c> the next state, and <c>2</c> the final state.
    /// </example>
    [<CompiledName("Scan")>]
    val scan<'T,'State> : folder:('State -> 'T -> 'State) -> state:'State -> source:seq<'T> -> seq<'State>

    /// <summary>Like <c>foldBack</c>, but returns the sequence of intermediary and final results.</summary>
    ///
    /// <remarks>This function returns a sequence that digests the whole initial sequence as soon as that
    /// sequence is iterated. As a result this function should not be used with large or infinite sequences.
    /// </remarks>
    ///
    /// <param name="folder">A function that updates the state with each element from the sequence.</param>
    /// <param name="source">The input sequence.</param>
    /// <param name="state">The initial state.</param>
    ///
    /// <returns>The resulting sequence of computed states.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// 
    /// <example id="scanback-1">Apply a list charges from back to front, and collect the running balances as each is applied:
    /// <code lang="fsharp">
    /// type Charge =
    ///     | In of int
    ///     | Out of int
    ///
    /// let inputs = [ In 1; Out 2; In 3 ]
    ///
    /// (inputs, 0) ||> Seq.scanBack (fun charge acc ->
    ///     match charge with
    ///     | In i -> acc + i
    ///     | Out o -> acc - o)
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 2; 1; 3; 0 }</c> by processing each input from back to front. Note <c>0</c> is the intial
    /// state, <c>3</c> the next state, <c>1</c> the next state, and <c>2</c> the final state, and the states
    /// are produced from back to front.
    /// </example>
    [<CompiledName("ScanBack")>]
    val scanBack<'T,'State> : folder:('T -> 'State -> 'State) -> source:seq<'T> -> state:'State -> seq<'State>

    /// <summary>Returns a sequence yielding one item only.</summary>
    ///
    /// <param name="value">The input item.</param>
    ///
    /// <returns>The result sequence of one item.</returns>
    /// 
    /// <example id="singleton-1">
    /// <code lang="fsharp">
    /// Seq.singleton 7
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 7 }</c>.
    /// </example>
    [<CompiledName("Singleton")>]
    val singleton: value:'T -> seq<'T>

    /// <summary>Returns a sequence that skips N elements of the underlying sequence and then yields the
    /// remaining elements of the sequence.</summary>
    ///
    /// <param name="count">The number of items to skip.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.InvalidOperationException">Thrown when count exceeds the number of elements
    /// in the sequence.</exception>
    ///
    /// <example id="skip-1">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "b"; "c"; "d"]
    ///
    /// inputs |> Seq.skip 2
    /// </code>
    /// Evaluates a sequence yielding the same results as <c>seq { "c"; "d" }</c>
    /// </example>
    ///
    /// <example id="skip-2">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "b"; "c"; "d"]
    ///
    /// inputs |> Seq.skip 5
    /// </code>
    /// Throws <c>ArgumentException</c>.
    /// </example>
    ///
    /// <example id="skip-3">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "b"; "c"; "d"]
    ///
    /// inputs |> Seq.skip -1
    /// </code>
    /// Evaluates a sequence yielding the same results as <c>seq { "a"; "b"; "c"; "d" }</c>.
    /// </example>
    [<CompiledName("Skip")>]
    val skip: count:int -> source:seq<'T> -> seq<'T>

    /// <summary>Returns a sequence that, when iterated, skips elements of the underlying sequence while the
    /// given predicate returns True, and then yields the remaining elements of the sequence.</summary>
    ///
    /// <param name="predicate">A function that evaluates an element of the sequence to a boolean value.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="skipwhile-1">
    /// <code lang="fsharp">
    /// let inputs = seq { "a"; "bbb"; "cc"; "d" }
    ///
    /// inputs |> Seq.skipWhile (fun x -> x.Length &lt; 3)
    /// </code>
    /// Evaluates a sequence yielding the same results as <c>seq { "bbb"; "cc"; "d" }</c>
    /// </example>
    [<CompiledName("SkipWhile")>]
    val skipWhile: predicate:('T -> bool) -> source:seq<'T> -> seq<'T>

    /// <summary>Yields a sequence ordered by keys.</summary>
    ///
    /// <remarks>This function returns a sequence that digests the whole initial sequence as soon as
    /// that sequence is iterated. As a result this function should not be used with
    /// large or infinite sequences.
    ///
    /// The function makes no assumption on the ordering of the original
    /// sequence and uses a stable sort, that is the original order of equal elements is preserved.</remarks>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// 
    /// <example id="sort-1">
    /// <code lang="fsharp">
    /// let input = seq { 8; 4; 3; 1; 6; 1 }
    ///
    /// Seq.sort input
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 1; 1 3; 4; 6; 8 }</c>.
    /// </example>
    [<CompiledName("Sort")>]
    val sort: source:seq<'T> -> seq<'T> when 'T : comparison

    /// <summary>Yields a sequence ordered using the given comparison function.</summary>
    ///
    /// <remarks>This function returns a sequence that digests the whole initial sequence as soon as
    /// that sequence is iterated. As a result this function should not be used with
    /// large or infinite sequences.
    ///
    /// The function makes no assumption on the ordering of the original
    /// sequence and uses a stable sort, that is the original order of equal elements is preserved.</remarks>
    ///
    /// <param name="comparer">The function to compare the collection elements.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <example id="sortwith-1">Sort a sequence of pairs using a comparison function that compares string lengths then index numbers:
    /// <code lang="fsharp">
    /// let compareEntries (n1: int, s1: string) (n2: int, s2: string) =
    ///     let c = compare s1.Length s2.Length
    ///     if c &lt;> 0 then c else
    ///     compare n1 n2
    ///
    /// let input = [ (0,"aa"); (1,"bbb"); (2,"cc"); (3,"dd") ]
    ///
    /// input |> Seq.sortWith compareEntries
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { (0, "aa"); (2, "cc"); (3, "dd"); (1, "bbb") }</c>.
    /// </example>
    [<CompiledName("SortWith")>]
    val sortWith: comparer:('T -> 'T -> int) -> source:seq<'T> -> seq<'T>

    /// <summary>Applies a key-generating function to each element of a sequence and yield a sequence ordered
    /// by keys.  The keys are compared using generic comparison as implemented by <see cref="M:Microsoft.FSharp.Core.Operators.compare"/>.</summary>
    ///
    /// <remarks>This function returns a sequence that digests the whole initial sequence as soon as
    /// that sequence is iterated. As a result this function should not be used with
    /// large or infinite sequences.
    ///
    /// The function makes no assumption on the ordering of the original
    /// sequence and uses a stable sort, that is the original order of equal elements is preserved.</remarks>
    ///
    /// <param name="projection">A function to transform items of the input sequence into comparable keys.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// 
    /// <example id="sortby-1">
    /// <code lang="fsharp">
    /// let input = [ "a"; "bbb"; "cccc"; "dd" ]
    ///
    /// input |> Seq.sortBy (fun s -> s.Length)
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { "a"; "dd"; "bbb"; "cccc" }</c>.
    /// </example>
    [<CompiledName("SortBy")>]
    val sortBy: projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> when 'Key : comparison

    /// <summary>Yields a sequence ordered descending by keys.</summary>
    ///
    /// <remarks>This function returns a sequence that digests the whole initial sequence as soon as
    /// that sequence is iterated. As a result this function should not be used with
    /// large or infinite sequences. The function makes no assumption on the ordering of the original
    /// sequence.
    ///
    /// This is a stable sort, that is the original order of equal elements is preserved.</remarks>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// 
    /// <example id="sortdescending-1">
    /// <code lang="fsharp">
    /// let input = seq { 8; 4; 3; 1; 6; 1 }
    ///
    /// input |> Seq.sortDescending
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 8; 6; 4; 3; 1; 1 }</c>.
    /// </example>
    [<CompiledName("SortDescending")>]
    val inline sortDescending: source:seq<'T> -> seq<'T> when 'T : comparison

    /// <summary>Applies a key-generating function to each element of a sequence and yield a sequence ordered
    /// descending by keys.  The keys are compared using generic comparison as implemented by <see cref="M:Microsoft.FSharp.Core.Operators.compare"/>.</summary>
    ///
    /// <remarks>This function returns a sequence that digests the whole initial sequence as soon as
    /// that sequence is iterated. As a result this function should not be used with
    /// large or infinite sequences. The function makes no assumption on the ordering of the original
    /// sequence.
    ///
    /// This is a stable sort, that is the original order of equal elements is preserved.</remarks>
    ///
    /// <param name="projection">A function to transform items of the input sequence into comparable keys.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// 
    /// <example id="sortbydescending-1">
    /// <code lang="fsharp">
    /// let input = ["a"; "bbb"; "cccc"; "dd"]
    ///
    /// input |> Seq.sortByDescending (fun s -> s.Length)
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { "cccc"; "bbb"; "dd"; "a" }</c>.
    /// </example>
    [<CompiledName("SortByDescending")>]
    val inline sortByDescending : projection:('T -> 'Key) -> source:seq<'T> -> seq<'T> when 'Key : comparison

    /// <summary>Returns the sum of the elements in the sequence.</summary>
    ///
    /// <remarks>The elements are summed using the <c>+</c> operator and <c>Zero</c> property associated with the generated type.</remarks>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The computed sum.</returns>
    /// 
    /// <example id="sum-1">
    /// <code lang="fsharp">
    /// let input = [ 1; 5; 3; 2 ]
    ///
    /// input |> Seq.sum
    /// </code>
    /// Evaluates to <c>11</c>.
    /// </example>
    [<CompiledName("Sum")>]
    val inline sum: source:seq<(^T)> -> ^T
                       when ^T : (static member ( + ) : ^T * ^T -> ^T)
                       and  ^T : (static member Zero : ^T)

    /// <summary>Returns the sum of the results generated by applying the function to each element of the sequence.</summary>
    ///
    /// <remarks>The generated elements are summed using the <c>+</c> operator and <c>Zero</c> property associated with the generated type.</remarks>
    ///
    /// <param name="projection">A function to transform items from the input sequence into the type that will be summed.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The computed sum.</returns>
    /// 
    /// <example id="sumby-1">
    /// <code lang="fsharp">
    /// let input = [ "aa"; "bbb"; "cc" ]
    ///
    /// input |> Seq.sumBy (fun s -> s.Length)
    /// </code>
    /// Evaluates to <c>7</c>.
    /// </example>
    [<CompiledName("SumBy")>]
    val inline sumBy: projection:('T -> ^U) -> source:seq<'T>  -> ^U
                        when ^U : (static member ( + ) : ^U * ^U -> ^U)
                        and  ^U : (static member Zero : ^U)

    /// <summary>Returns a sequence that skips 1 element of the underlying sequence and then yields the
    /// remaining elements of the sequence.</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.InvalidOperationException">Thrown when the input sequence is empty.</exception>
    ///
    /// <example id="tail-1">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "bb"; "ccc"]
    ///
    /// inputs |> Seq.tail
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { "bb"; "ccc" }</c>
    /// </example>
    ///
    [<CompiledName("Tail")>]
    val tail: source:seq<'T> -> seq<'T>

    /// <summary>Returns the first N elements of the sequence.</summary>
    ///
    /// <remarks>Throws <c>InvalidOperationException</c>
    /// if the count exceeds the number of elements in the sequence. <c>Seq.truncate</c>
    /// returns as many items as the sequence contains instead of throwing an exception.</remarks>
    ///
    /// <param name="count">The number of items to take.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input sequence is empty and the count is greater than zero.</exception>
    /// <exception cref="T:System.InvalidOperationException">Thrown when count exceeds the number of elements
    /// in the sequence.</exception>
    ///
    /// <example id="take-1">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "b"; "c"; "d"]
    ///
    /// inputs |> Seq.take 2
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>["a"; "b"]</c>
    /// </example>
    ///
    /// <example id="take-2">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "b"; "c"; "d"]
    ///
    /// inputs |> Seq.take 6
    /// </code>
    /// Throws <c>InvalidOperationException</c>.
    /// </example>
    ///
    /// <example id="take-3">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "b"; "c"; "d"]
    ///
    /// inputs |> Seq.take 0
    /// </code>
    /// Evaluates to a sequence yielding no results.
    /// </example>
    [<CompiledName("Take")>]
    val take: count:int -> source:seq<'T> -> seq<'T>

    /// <summary>Returns a sequence that, when iterated, yields elements of the underlying sequence while the
    /// given predicate returns True, and then returns no further elements.</summary>
    ///
    /// <param name="predicate">A function that evaluates to false when no more items should be returned.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="takewhile-1">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "bb"; "ccc"; "d"]
    ///
    /// inputs |> Seq.takeWhile (fun x -> x.Length &lt; 3)
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { "a"; "bb" }</c>
    /// </example>
    [<CompiledName("TakeWhile")>]
    val takeWhile: predicate:('T -> bool) -> source:seq<'T> -> seq<'T>

    /// <summary>Builds an array from the given collection.</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="toarray-1">
    /// <code lang="fsharp">
    /// let inputs = seq { 1; 2; 5 }
    ///
    /// inputs |> Seq.toArray
    /// </code>
    /// Evaluates to <c>[| 1; 2; 5 |]</c>.
    /// </example>
    [<CompiledName("ToArray")>]
    val toArray: source:seq<'T> -> 'T[]

    /// <summary>Builds a list from the given collection.</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result list.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="tolist-1">
    /// <code lang="fsharp">
    /// let inputs = seq { 1; 2; 5 }
    ///
    /// inputs |> Seq.toList
    /// </code>
    /// Evaluates to <c>[ 1; 2; 5 ]</c>.
    /// </example>
    [<CompiledName("ToList")>]
    val toList: source:seq<'T> -> 'T list

    /// <summary>Returns the first element for which the given function returns True.
    /// Return None if no such element exists.</summary>
    ///
    /// <param name="predicate">A function that evaluates to a Boolean when given an item in the sequence.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The found element or None.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="tryfind-1">Try to find the first even number:
    /// <code lang="fsharp">
    /// let inputs = [1; 2; 3]
    ///
    /// inputs |> Seq.tryFind (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>Some 2</c>
    /// </example>
    ///
    /// <example id="tryfind-2">Try to find the first even number:
    /// <code lang="fsharp">
    /// let inputs = [1; 5; 3]
    ///
    /// inputs |> Seq.tryFind (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>None</c>
    /// </example>
    [<CompiledName("TryFind")>]
    val tryFind: predicate:('T -> bool) -> source:seq<'T> -> 'T option

    /// <summary>Returns the last element for which the given function returns True.
    /// Return None if no such element exists.</summary>
    ///
    /// <remarks>This function digests the whole initial sequence as soon as it is called. As a
    /// result this function should not be used with large or infinite sequences.</remarks>
    ///
    /// <param name="predicate">A function that evaluates to a Boolean when given an item in the sequence.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The found element or None.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="tryfindback-1">Try to find the first even number from the back:
    /// <code lang="fsharp">
    /// let inputs = [1; 2; 3; 4; 5]
    ///
    /// inputs |> Seq.tryFindBack (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>Some 4</c>
    /// </example>
    ///
    /// <example id="tryfindback-2">Try to find the first even number from the back:
    /// <code lang="fsharp">
    /// let inputs = [1; 5; 3]
    ///
    /// inputs |> Seq.tryFindBack (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>None</c>
    /// </example>
    [<CompiledName("TryFindBack")>]
    val tryFindBack: predicate:('T -> bool) -> source:seq<'T> -> 'T option

    /// <summary>Returns the index of the first element in the sequence
    /// that satisfies the given predicate. Return <c>None</c> if no such element exists.</summary>
    ///
    /// <param name="predicate">A function that evaluates to a Boolean when given an item in the sequence.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The found index or None.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="tryfindindex-1">Try to find the index of the first even number:
    /// <code lang="fsharp">
    /// let inputs = [1; 2; 3; 4; 5]
    ///
    /// inputs |> Seq.tryFindIndex (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>Some 1</c>
    /// </example>
    ///
    /// <example id="tryfindindex-2">Try to find the index of the first even number:
    /// <code lang="fsharp">
    /// let inputs = [1; 3; 5; 7]
    ///
    /// inputs |> Seq.tryFindIndex (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>None</c>
    /// </example>
    [<CompiledName("TryFindIndex")>]
    val tryFindIndex : predicate:('T -> bool) -> source:seq<'T> -> int option

    /// <summary>Tries to find the nth element in the sequence.
    /// Returns <c>None</c> if index is negative or the input sequence does not contain enough elements.</summary>
    ///
    /// <param name="index">The index of element to retrieve.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The nth element of the sequence or <c>None</c>.</returns>
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="tryitem-1">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "b"; "c"]
    ///
    /// inputs |> Seq.tryItem 1
    /// </code>
    /// Evaluates to <c>Some "b"</c>.
    /// </example>
    ///
    /// <example id="tryitem-2">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "b"; "c"]
    ///
    /// inputs |> Seq.tryItem 4
    /// </code>
    /// Evaluates to <c>None</c>.
    /// </example>
    [<CompiledName("TryItem")>]
    val tryItem: index:int -> source:seq<'T> -> 'T option

    /// <summary>Returns the index of the last element in the sequence
    /// that satisfies the given predicate. Return <c>None</c> if no such element exists.</summary>
    ///
    /// <remarks>This function digests the whole initial sequence as soon as it is called. As a
    /// result this function should not be used with large or infinite sequences.</remarks>
    ///
    /// <param name="predicate">A function that evaluates to a Boolean when given an item in the sequence.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The found index or <c>None</c>.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="tryfindindexback-1">Try to find the index of the first even number from the back:
    /// <code lang="fsharp">
    /// let inputs = [1; 2; 3; 4; 5]
    ///
    /// inputs |> Seq.tryFindIndexBack (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>Some 3</c>
    /// </example>
    ///
    /// <example id="tryfindindexback-2">Try to find the index of the first even number from the back:
    /// <code lang="fsharp">
    /// let inputs = [1; 3; 5; 7]
    ///
    /// inputs |> Seq.tryFindIndexBack (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>None</c>
    /// </example>
    [<CompiledName("TryFindIndexBack")>]
    val tryFindIndexBack : predicate:('T -> bool) -> source:seq<'T> -> int option

    /// <summary>Applies the given function to successive elements, returning the first
    /// result where the function returns "Some(x)".</summary>
    ///
    /// <param name="chooser">A function that transforms items from the input sequence into options.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The chosen element or <c>None</c>.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="trypick-1">
    /// <code lang="fsharp">
    /// let input = [1; 2; 3]
    ///
    /// input |> Seq.tryPick (fun n -> if n % 2 = 0 then Some (string n) else None)
    /// </code>
    /// Evaluates to <c>Some "2"</c>.
    /// </example>
    ///
    /// <example id="trypick-2">
    /// <code lang="fsharp">
    /// let input = [1; 2; 3]
    ///
    /// input |> Seq.tryPick (fun n -> if n > 3 = 0 then Some (string n) else None)
    /// </code>
    /// Evaluates to <c>None</c>.
    /// </example>
    [<CompiledName("TryPick")>]
    val tryPick: chooser:('T -> 'U option) -> source:seq<'T> -> 'U option

    /// <summary>Returns the transpose of the given sequence of sequences.</summary>
    ///
    /// <remarks>This function returns a sequence that digests the whole initial sequence as soon as
    /// that sequence is iterated. As a result this function should not be used with
    /// large or infinite sequences.</remarks>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The transposed sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="transpose-1">
    /// <code lang="fsharp">
    /// let inputs =
    ///     [ [ 10; 20; 30 ]
    ///       [ 11; 21; 31 ] ]
    ///
    /// inputs |> Seq.transpose
    /// </code>
    /// Evaluates to a sequence of sequences yielding the same results as <c>[ [10; 11]; [20; 21]; [30; 31] ]</c>.
    /// </example>
    [<CompiledName("Transpose")>]
    val transpose: source:seq<'Collection> -> seq<seq<'T>> when 'Collection :> seq<'T>

    /// <summary>Returns a sequence that when enumerated returns at most N elements.</summary>
    ///
    /// <param name="count">The maximum number of items to enumerate.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="truncate-1">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "b"; "c"; "d"]
    ///
    /// inputs |> Seq.truncate 2
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { "a"; "b" }</c>
    /// </example>
    ///
    /// <example id="truncate-2">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "b"; "c"; "d"]
    ///
    /// inputs |> Seq.truncate 6
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { "a"; "b"; "c"; "d" }</c>
    /// </example>
    ///
    /// <example id="truncate-3">
    /// <code lang="fsharp">
    /// let inputs = ["a"; "b"; "c"; "d"]
    ///
    /// inputs |> Seq.truncate 0
    /// </code>
    /// Evaluates to the empty sequence.
    /// </example>
    [<CompiledName("Truncate")>]
    val truncate: count:int -> source:seq<'T> -> seq<'T>

    /// <summary>Returns a sequence that contains the elements generated by the given computation.
    /// The given initial <c>state</c> argument is passed to the element generator.
    /// For each IEnumerator elements in the stream are generated on-demand by applying the element
    /// generator, until a None value is returned by the element generator. Each call to the element
    /// generator returns a new residual <c>state</c>.</summary>
    ///
    /// <remarks>The stream will be recomputed each time an IEnumerator is requested and iterated for the Seq.</remarks>
    ///
    /// <param name="generator">A function that takes in the current state and returns an option tuple of the next
    /// element of the sequence and the next state value.</param>
    /// <param name="state">The initial state value.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <example id="unfold-1">
    /// <code lang="fsharp">
    /// 1 |> Seq.unfold (fun state -> if state > 100 then None else Some (state, state * 2))
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 1; 2; 4; 8; 16; 32; 64 }</c>
    /// </example>
    ///
    /// <example id="unfold-2">
    /// <code lang="fsharp">
    /// 1I |> Seq.unfold (fun state -> Some (state, state * 2I))
    /// </code>
    /// Evaluates to an infinite sequence yielding the results <c>seq { 1I; 2I; 4I; 8I; ... }</c>
    /// </example>
    [<CompiledName("Unfold")>]
    val unfold: generator:('State -> ('T * 'State) option) -> state:'State -> seq<'T>

    /// <summary>Returns a sequence yielding sliding windows containing elements drawn from the input
    /// sequence. Each window is returned as a fresh array.</summary>
    ///
    /// <param name="windowSize">The number of elements in each window.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when windowSize is not positive.</exception>
    /// 
    /// <example id="windowed-1">
    /// <code lang="fsharp">
    /// let inputs = [1; 2; 3; 4; 5]
    ///
    /// inputs |> Seq.windowed 3
    /// </code>
    /// Evaluates to a sequence of arrays yielding the results <c>seq { [| 1; 2; 3 |]; [| 2; 3; 4 |]; [| 3; 4; 5 |] }</c>
    /// </example>
    [<CompiledName("Windowed")>]
    val windowed: windowSize:int -> source:seq<'T> -> seq<'T[]>

    /// <summary>Combines the two sequences into a sequence of pairs. The two sequences need not have equal lengths:
    /// when one sequence is exhausted any remaining elements in the other
    /// sequence are ignored.</summary>
    ///
    /// <param name="source1">The first input sequence.</param>
    /// <param name="source2">The second input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input sequences is null.</exception>
    ///
    /// <example id="zip-1">
    /// <code lang="fsharp">
    /// let numbers = [1; 2]
    /// let names = ["one"; "two"]
    ///
    /// Seq.zip numbers names
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { (1, "one"); (2, "two") }</c>.
    /// </example>
    [<CompiledName("Zip")>]
    val zip: source1:seq<'T1> -> source2:seq<'T2> -> seq<'T1 * 'T2>

    /// <summary>Combines the three sequences into a sequence of triples. The sequences need not have equal lengths:
    /// when one sequence is exhausted any remaining elements in the other
    /// sequences are ignored.</summary>
    ///
    /// <param name="source1">The first input sequence.</param>
    /// <param name="source2">The second input sequence.</param>
    /// <param name="source3">The third input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when any of the input sequences is null.</exception>
    ///
    /// <example id="zip3-1">
    /// <code lang="fsharp">
    /// let numbers = [1; 2]
    /// let names = ["one"; "two"]
    /// let roman = ["I"; "II"]
    ///
    /// Seq.zip3 numbers names roman
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { (1, "one", "I"); (2, "two", "II") }</c>.
    /// </example>
    [<CompiledName("Zip3")>]
    val zip3: source1:seq<'T1> -> source2:seq<'T2> -> source3:seq<'T3> -> seq<'T1 * 'T2 * 'T3>

    /// <summary>Return a new sequence with the item at a given index removed.</summary>
    ///
    /// <param name="index">The index of the item to be removed.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when index is outside 0..source.Length - 1</exception>
    ///
    /// <example id="removeAt-1">
    /// <code>
    /// seq { 0; 1; 2 } |> Seq.removeAt 1
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 0; 2 }</c>.
    /// </example>
    [<CompiledName("RemoveAt")>]
    val removeAt: index: int -> source: seq<'T> -> seq<'T>

    /// <summary>Return a new sequence with the number of items starting at a given index removed.</summary>
    ///
    /// <param name="index">The index of the item to be removed.</param>
    /// <param name="count">The number of items to remove.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when index is outside 0..source.Length - count</exception>
    ///
    /// <example id="removeManyAt-1">
    /// <code>
    /// seq { 0; 1; 2; 3 } |> Seq.removeManyAt 1 2
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 0; 3 }</c>.
    /// </example>
    [<CompiledName("RemoveManyAt")>]
    val removeManyAt: index: int -> count: int -> source: seq<'T> -> seq<'T>

    /// <summary>Return a new sequence with the item at a given index set to the new value.</summary>
    ///
    /// <param name="index">The index of the item to be replaced.</param>
    /// <param name="value">The new value.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when index is outside 0..source.Length - 1</exception>
    ///
    /// <example id="updateAt-1">
    /// <code>
    /// seq { 0; 1; 2 } |> Seq.updateAt 1 9
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 0; 9; 2 }</c>.
    /// </example>
    [<CompiledName("UpdateAt")>]
    val updateAt: index: int -> value: 'T -> source: seq<'T> -> seq<'T>

    /// <summary>Return a new sequence with a new item inserted before the given index.</summary>
    ///
    /// <param name="index">The index where the item should be inserted.</param>
    /// <param name="value">The value to insert.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when index is below 0 or greater than source.Length.</exception>
    ///
    /// <example id="insertAt-1">
    /// <code>
    /// seq { 0; 1; 2 } |> Seq.insertAt 1 9
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 0; 9; 1; 2 }</c>.
    /// </example>
    [<CompiledName("InsertAt")>]
    val insertAt: index: int -> value: 'T -> source: seq<'T> -> seq<'T>

    /// <summary>Return a new sequence with new items inserted before the given index.</summary>
    ///
    /// <param name="index">The index where the items should be inserted.</param>
    /// <param name="values">The values to insert.</param>
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The result sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when index is below 0 or greater than source.Length.</exception>
    ///
    /// <example id="insertManyAt-1">
    /// <code>
    ///     seq { 0; 1; 2 } |> Seq.insertManyAt 1 [8; 9]
    /// </code>
    /// Evaluates to a sequence yielding the same results as <c>seq { 0; 8; 9; 1; 2 }</c>.
    /// </example>
    [<CompiledName("InsertManyAt")>]
    val insertManyAt: index: int -> values: seq<'T> -> source: seq<'T> -> seq<'T>
